#!/bin/bash
#Author:Sumn255 Sumn255@gmail.com
#fork from https://github.com/qinghon/BonusCloud-Node

. /lib/lsb/init-functions
LOG_FILE="ins.log"
support_os=(
    centos
    debian
    fedora
    raspbian
    ubuntu
    archlinux
    manjaro
)
# test on ubuntu only!

echoerr(){ printf "\033[1;31m$1\033[0m" 
}
echoinfo(){ printf "\033[1;32m$1\033[0m"
}
echowarn(){ printf "\033[1;33m$1\033[0m"
}
echo-(){
    local columns
    columns=$(stty size 2>/dev/null|awk '{print $2}')
    columns=${columns:-80}
    yes "-"|sed "${columns}q"|tr -d '\n'
    printf "\n"
}
log(){
    timeOut="[$(date '+%Y-%m-%d %H:%M:%S')]"
    case $1 in
        "[error]" )
            echo "${timeOut} $1 $2" >>$LOG_FILE
            echoerr "${timeOut} $1 $2\n"
            ;;
        "[info]" )
            echo "${timeOut} $1 $2" >>$LOG_FILE
            [[ "${DISPLAYINFO}" == "1" ]]&&echoinfo "${timeOut} $1 $2\n"
            ;;
        "[warn]" )
            echo "${timeOut} $1 $2" >>$LOG_FILE
            echowarn "${timeOut} $1 $2\n"
            ;;
    esac
}
sysArch(){
    ARCH=$(uname -m)
    if   [[ "$ARCH" == "i686" ]] || [[ "$ARCH" == "i386" ]]; then
        VDIS="32"
    elif [[ "$ARCH" == "x86_64" ]] ; then
        VDIS="amd64"
    elif [[ "$ARCH" == *"armv7"* ]] || [[ "$ARCH" == "armv6l" ]]; then
        VDIS="arm"
    elif [[ "$ARCH" == *"armv8"* ]] || [[ "$ARCH" == "aarch64" ]]; then
        VDIS="arm64"
    elif [[ "$ARCH" == *"mips64le"* ]]; then
        VDIS="mips64le"
    elif [[ "$ARCH" == *"mips64"* ]]; then
        VDIS="mips64"
    elif [[ "$ARCH" == *"mipsle"* ]]; then
        VDIS="mipsle"
    elif [[ "$ARCH" == *"mips"* ]]; then
        VDIS="mips"
    elif [[ "$ARCH" == *"s390x"* ]]; then
        VDIS="s390x"
    elif [[ "$ARCH" == "ppc64le" ]]; then
        VDIS="ppc64le"
    elif [[ "$ARCH" == "ppc64" ]]; then
        VDIS="ppc64"
    fi
    return 0
}
sys_codename(){
    if  which lsb_release >/dev/null  2>&1; then
        OS_CODENAME=$(lsb_release -cs)
    fi
}
run_as_root(){
    # 检测是否有root权限
    if [[ $(id -u) -eq 0 ]]; then
        return 0
    fi
    if which sudo >/dev/null 2>&1; then
        echoerr "Please run as sudo:\nsudo bash $0 $1\n"
        exit 1
    else
        echoerr "Please run as root user!\n"
        exit 2
    fi
}
env_check(){
    # 检查环境
    # Detection package manager
    if which apt >/dev/null 2>&1 ; then
        echoinfo "Find apt\n"
        PG="apt"
    elif which yum >/dev/null 2>&1 ; then
        echoinfo "Find yum\n"
        PG="yum"
    elif which pacman>/dev/null 2>&1 ; then
        log "[info]" "Find pacman"
        PG="pacman"
    else
        log "[error]" "\"apt\" or \"yum\" ,not found ,exit "
        exit 1
    fi
    ret_c=$(which curl >/dev/null 2>&1;echo $?)
    ret_w=$(which wget >/dev/null 2>&1;echo $?)
    case ${PG} in
        apt ) $PG install -y curl wget apt-transport-https pciutils;;
        yum ) $PG install -y curl wget ;;
    esac
    # Check if the system supports
    # 使用screenfetch工具检测系统发行版
    [ ! -s $TMP/screenfetch ]&&wget  -nv -O $TMP/screenfetch "https://raw.githubusercontent.com/KittyKatt/screenFetch/master/screenfetch-dev" 
    chmod +x $TMP/screenfetch
    OS_line=$($TMP/screenfetch -n |grep 'OS:')
    OS=$(echo "$OS_line"|awk '{print $3}'|tr '[:upper:]' '[:lower:]')
    if [[ -z "$OS" ]]; then
        source /etc/os-release
        if echo "${support_os[@]}"|grep -w "$ID" &>/dev/null  ; then
            OS="$ID"
            case $ID in
                ubuntu ) OS_CODENAME="$VERSION_CODENAME" ;;
            esac
        else
            read -r -p "The release version is not detected, please enter it manually,like \"ubuntu\"" OS
        fi
    fi
    if ! echo "${support_os[@]}"|grep -w "$OS" &>/dev/null ; then
        log "[error]" "This system is not supported by docker, exit"
        exit 1
    else
        log "[info]" "system : $OS ;Package manager $PG"
    fi
}

DOC_LOW="1.11.1"
DOC_HIG="19.03.9"
function version_ge() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"; }
function version_le() { test "$(echo "$@" | tr " " "\n" | sort -V  | head -n 1)" == "$1"; }
check_doc(){
    # 检查docker 安装状态和版本
    retd=$(which docker>/dev/null;echo $?)
    if [ "${retd}" -ne 0 ]; then
        log "[info]" "docker not found"
        return 1
    fi
    doc_v=$(docker version --format "{{.Server.Version}}")
    if version_ge "${doc_v}" "${DOC_LOW}" && version_le "${doc_v}" "${DOC_HIG}" ; then
        log "[info]" "dockerd version ${doc_v} above ${DOC_LOW} and below ${DOC_HIG}"
        return 0
    else
        log "[info]" "docker version ${doc_v} fail"
        return 2
    fi
}

ins_docker(){
    # 安装docker
    check_doc
    ret=$?
    if [[ ${ret} -eq 0 || ${ret} -eq 2 ]]   ; then
        log "[info]" "docker was found! skiped"
        return 0
    fi
    env_check
    if [[ "$PG" == "apt" ]]; then
        # Install docker with APT
        # apt 安装docker
        curl -fsSL "https://download.docker.com/linux/$OS/gpg" | apt-key add -
        echo "deb https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/$OS  $OS_CODENAME stable"  >/etc/apt/sources.list.d/docker.list
        apt update
        # 遍历版本号,安装不能超过限制的版本
        for line in $(apt-cache madison docker-ce|awk '{print $3}') ; do
            if version_le "$(echo "$line" |grep -E -o '([0-9]+\.){2}[0-9]+')" "$DOC_HIG" ; then
                apt-mark unhold docker-ce
                apt install -y --allow-downgrades docker-ce="$line" 
                break
            fi
        done
        apt-mark hold docker-ce 
    elif [[ "$PG" == "yum" ]]; then
        # Install docker with yum
        # 同上
        yum install -y yum-utils
        yum-config-manager --add-repo  https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
        yum makecache
        for line in $(yum list docker-ce --showduplicates|grep 'docker-ce'|awk '{print $2}'|sort -r) ; do
            if version_le "$(echo "$line" |grep -E -o '([0-9]+\.){2}[0-9]+')" "$DOC_HIG" ; then
                yum remove  -y docer-ce docker-ce-cli
                if echo "$line"|grep -q ':' ; then
                    line=$(echo "$line"|awk -F: '{print $2}')
                fi
                yum install -y docker-ce-"$line" 
                break
            fi
        done
    elif [[ "$PG" == "pacman" ]]; then
        # Install docker with pacman
        # 同上
        pacman -Sy docker-ce # didn't check version yet
    else 
        log "[error]" "package manager ${PG} not support "
        return 1
    fi
    usermod -aG docker $USER
    #systemctl enable docker.service
    systemctl start docker.service
    check_doc
    ret=$?
    if [[ ${ret} -eq 1 || ${ret} -eq 2 ]]  ; then
        log "[error]" "docker install fail,please check ${PG} environment"
        exit 1
    else
        log "[info]" "${PG} install -y  docker-ce-$line "
        systemctl disable docker &&systemctl stop docker
    fi
}

jq_yum_ins(){
    # 安装EPEL仓库就为了装个jq,可恶
    wget -O $TMP/epel-release-latest-7.noarch.rpm http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
    rpm -ivh $TMP/epel-release-latest-7.noarch.rpm
    yum install -y jq
}
ins_jq(){
    # 安装jq json文件分析工具
    if which jq>/dev/null 2>&1; then
        return
    fi
    env_check
    case $PG in
        apt     ) $PG install -y jq ;;
        yum     ) jq_yum_ins ;;
        pacman  ) $PG -Sy jq ;;
    esac
    if ! which jq>/dev/null 2>&1; then
        echoerr "jq install fail,please check you package sources and try \`$PG install jq -y\`\n"
    fi
}

release_files(){
    cp -f beneficiary.json /boot/beneficiary.json
    mkdir -p /etc/docker
    cp -f target/daemon.json /etc/docker/daemon.json

    mkdir -p /etc/nkn-commercial
    cp -f target/etc-nkn-commercial/config.json /etc/nkn-commercial/config.json
    cp -f target/nkn-commercial.service /lib/systemd/system/nkn-commercial.service
    ln -sf /lib/systemd/system/nkn-commercial.service $DIR_INSTALL/etc/systemd/system/multi-user.target.wants/nkn-commercial.service
    cp target/nkn-commercial /usr/sbin/; chmod +x /usr/sbin/nkn-commercial

    mkdir -p /etc/nshd
    cp -f target/etc-nshd/authorized_pubkeys /etc/nshd/authorized_pubkeys
    cp -f target/nshd.service /lib/systemd/system/nshd.service
    cp target/nshd /usr/sbin/; chmod +x /usr/sbin/nshd

    mkdir -p /etc/dchat
    cp -f target/dchat/nkn_contacts /etc/dchat/nkn_contacts
    cp target/dchat-cli /usr/bin/ ;chmod +x /usr/bin/dchat-cli

    mv /lib/systemd/system/docker.service /lib/systemd/system/docker.service.bak
    cp -f target/docker.service /lib/systemd/system/docker.service

    cp -f target/start_worker.sh /root/start_worker.sh;chmod +x /root/start_worker.sh
    cp -f target/firstboot.sh /root/firstboot.sh;chmod +x /root/firstboot.sh
    cp target/99-local.rules.1 /etc/udev/rules.d/99-local.rules.1
    cp -f target/usb-mount.sh /usr/local/bin/usb-mount.sh;chmod +x /usr/local/bin/usb-mount.sh
    cp -f target/nkn-checker.sh /usr/local/bin/nkn-checker.sh;chmod +x /usr/local/bin/nkn-checker.sh
    cp -f target/swarm-checker.sh /usr/local/bin/swarm-checker.sh;chmod +x /usr/local/bin/swarm-checker.sh
    cp -f target/init-worker.sh /usr/local/bin/init-worker.sh;chmod +x /usr/local/bin/init-worker.sh

    mv /etc/rc.local /etc/rc.local.bak
    cp -f target/rc.local /etc/rc.local
    mv /etc/crontab /etc/crontab.bak
    cp -f target/crontab /etc/crontab
}

set_account(){
    DIR_INSTALL=""
    #generate ${DIR_INSTALL}/etc/docker/daemon.json
    log "Generating docker config"
    BENEF=$(cat /boot/beneficiary.json |jq '.beneficiary // empty' |sed 's/"//g')
    ERC_ADDR=$(cat /boot/beneficiary.json |jq '.ercAddr // empty' |sed 's/"//g')
    REFER=$(cat /boot/beneficiary.json |jq '.referrer // empty' |sed 's/"//g')
    CONTACT=$(cat /boot/beneficiary.json |jq '.contact // empty' |sed 's/"//g')
    [ -z "${BENEF}" ] && BENEF="NKNaaaaaaaaaaaaaaaaaaaaaaaaaaaeJ6gxa"
    [ -z "${ERC_ADDR}" ] && ERC_ADDR="0x68cb76dea7d391c5e5bb51ebbcd30001b0d9fe12"
    if [ -z ${REFER} ]; then
        LBS="$(cat /etc/docker/daemon.json |jq '(.labels // []) + ["beneficiary='${BENEF}'", "ercAddr='${ERC_ADDR}'", "contact='${CONTACT}'"]')"
    else
        LBS="$(cat /etc/docker/daemon.json |jq '(.labels // []) + ["beneficiary='${BENEF}'", "ercAddr='${ERC_ADDR}'", "contact='${CONTACT}'", "referrer='${REFER}'"]')"
    fi
    JSON="$(cat /etc/docker/daemon.json |jq '. + {"labels": '"${LBS}"'}')"
    [ -n "${JSON}" ] && echo ${JSON} |jq . > ${DIR_INSTALL}/etc/docker/daemon.json

    #generate ${DIR_INSTALL}/etc/nkn-commercial/config.json
    log "Generating nkn-commercial config"
    JSON=$(cat /etc/nkn-commercial/config.json |jq '. + {"BeneficiaryAddr":"'${BENEF}'"}')
    [ -n "${JSON}" ] && echo ${JSON} |jq . > ${DIR_INSTALL}/etc/nkn-commercial/config.json

    log "Assign uniq DevID and set Hostname"
    #generate ${DIR_INSTALL}/etc/nshd/wallet.[json|pswd]
    nshd -b ${DIR_INSTALL}/etc/nshd addr	### init wallet
    nshID=$(nshd -b ${DIR_INSTALL}/etc/nshd addr |cut -c 1-8)
    echo "NKN-N1-${nshID}" > $DIR_INSTALL/etc/hostname

    #Send dchar msg
    log "Send dchat msg to owner"
    echo ${CONTACT} > ${DIR_INSTALL}/etc/dchat/owner_contacts
    NOTICE=$(cd ${DIR_INSTALL}/etc/dchat && cat ./owner_contacts ./nkn_contacts |tr '\n' ',' |sed 's/,$//g')
    echo "Flush N1 with ${BENEF} Done. Shutdown the Dev:${nshID}" |dchat-cli -b $DIR_INSTALL/etc/nshd -to "$NOTICE"

    # default systemctl start
    ln -sf /lib/systemd/system/nshd.service $DIR_INSTALL/etc/systemd/system/multi-user.target.wants/nshd.service

}



run_as_root
sysArch ; [ "$VDIS" != "arm64" ] && echo "not support such arch!" && exit 1
sys_codename
ins_docker
ins_jq
release_files
set_account
echo "install done!please plugin harddisk and reboot!"
echo "安装完成！请插入硬盘重启！"
sync
